﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework;
using SimpleGameData.MinMax;
using Microsoft.Xna.Framework.Graphics;

namespace SimpleGameData.GameObjects.Particles
{
    public class EmitterData
    {
        #region Fields

        // The texture path of this particles texture
        private string texturePath;
        // The texture to be used for the particles
        private Texture2D texture;
        // The position of the emitter
        private Vector2 emitterPosition;
        // The amount of particles of this emitter
        private int particleCount;
        // The maximum amount of particles which can be spawned per update
        private int particleMaxSpawnCount;
        // true = rotation direction is randomed between clockwise and counter-clockwise
        // false = rotation is not randomed and isRotationClockwise is used instead
        private bool isRotationDirectionRandom;
        // true = rotation is clockwise | false = rotation is counter-clockwise
        private bool isRotationClockwise = true;

        #endregion

        #region Min/Max Fields

        // min and max angle of particle emission to be randomed between
        private MinMaxFloat emissionAngle;
        // min and max life time of the particles to be randomed between
        private MinMaxFloat lifeMinMax;
        // min and max velocity of the particles to be randomed between
        private MinMaxFloat velocityMinMax;
        // min and max acceleration of the particles to be randomed between
        private MinMaxFloat accelerationMinMax;
        // min and max rotation of the particles to be randomed between
        private MinMaxFloat rotationMinMax;
        // min and max rotationspeed of the particles to be randomed between
        private MinMaxFloat rotationSpeedMinMax;
        // min and max scale of the particles to be randomed between
        private MinMaxFloat scaleMinMax;
        // min and max scale shift per update of the particles to be randomed between
        private MinMaxFloat scaleShiftMinMax;
        // min and max red color start value of the particles to be randomed between
        private MinMaxFloat colorRedStartMinMax;
        // min and max red color end value of the particles to be randomed between
        private MinMaxFloat colorRedEndMinMax;
        // min and max green color start value of the particles to be randomed between
        private MinMaxFloat colorGreenStartMinMax;
        // min and max green color end value of the particles to be randomed between
        private MinMaxFloat colorGreenEndMinMax;
        // min and max blue color start value of the particles to be randomed between
        private MinMaxFloat colorBlueStartMinMax;
        // min and max blue color end value of the particles to be randomed between
        private MinMaxFloat colorBlueEndMinMax;
        // min and max alpha start value of the particles to be randomed between
        private MinMaxFloat alphaValueStartMinMax;
        // min and max alpha end value of the particles to be randomed between
        private MinMaxFloat alphaValueEndMinMax;


        #endregion

        #region Properties

        /// <summary>
        /// The path of the texture represented by a string.
        /// </summary>
        public string TexturePath
        {
            get { return texturePath; }
            set { texturePath = value; }
        }

        /// <summary>
        /// The texture of the DrawableGameObject.
        /// </summary>
        [ContentSerializerIgnore]
        public Texture2D Texture
        {
            get { return texture; }
            set { texture = value; }
        }

        /// <summary>
        /// The X, Y position of the game object.
        /// </summary>
        public Vector2 EmitterPosition
        {
            get { return emitterPosition; }
            set { emitterPosition = value; }
        }

        /// <summary>
        /// The amount of particles of this emitter
        /// </summary>
        public int ParticleCount
        {
            get { return particleCount; }
            set { particleCount = value; }
        }

        /// <summary>
        /// The maximum amount of particles which can be spawned per update
        /// </summary>
        public int ParticleMaxSpawnCount
        {
            get { return particleMaxSpawnCount; }
            set { particleMaxSpawnCount = value; }
        }

        /// <summary>
        /// true = rotation direction is randomed between clockwise and counter-clockwise
        /// false = rotation is not randomed and isRotationClockwise is used instead
        /// </summary>
        public bool IsRotationDirectionRandom
        {
            get { return isRotationDirectionRandom; }
            set { isRotationDirectionRandom = value; }
        }

        /// <summary>
        /// true = rotation is clockwise | false = rotation is counter-clockwise
        /// </summary>
        [ContentSerializerAttribute(Optional = true)]
        public bool IsRotationClockwise
        {
            get { return isRotationClockwise; }
            set { isRotationClockwise = value; }
        }

        #endregion

        #region Min/Max Properties

        /// <summary>
        /// min and max angle of particle emission to be randomed between
        /// </summary>
        public MinMaxFloat EmissionAngle
        {
            get { return emissionAngle; }
            set { emissionAngle = value; }
        }

        /// <summary>
        /// Min and max life time of the particles to be randomed between
        /// </summary>
        public MinMaxFloat LifeMinMax
        {
            get { return velocityMinMax; }
            set { velocityMinMax = value; }
        }

        /// <summary>
        /// Min and max velocity of the particles to be randomed between
        /// </summary>
        public MinMaxFloat VelocityMinMax
        {
            get { return lifeMinMax; }
            set { lifeMinMax = value; }
        }

        /// <summary>
        /// Min and max acceleration of the particles to be randomed between
        /// </summary>
        public MinMaxFloat AccelerationMinMax
        {
            get { return accelerationMinMax; }
            set { accelerationMinMax = value; }
        }

        /// <summary>
        /// Min and max rotation of the particles to be randomed between
        /// </summary>
        public MinMaxFloat RotationMinMax
        {
            get { return rotationMinMax; }
            set { rotationMinMax = value; }
        }

        /// <summary>
        /// Min and max rotationSpeed of the particles to be randomed between
        /// </summary>
        public MinMaxFloat RotationSpeedMinMax
        {
            get { return rotationSpeedMinMax; }
            set { rotationSpeedMinMax = value; }
        }

        /// <summary>
        /// Min and max scale of the particles to be randomed between
        /// </summary>
        public MinMaxFloat ScaleMinMax
        {
            get { return scaleMinMax; }
            set { scaleMinMax = value; }
        }

        /// <summary>
        /// Min and max scaleShift of the particles to be randomed between
        /// </summary>
        public MinMaxFloat ScaleShiftMinMax
        {
            get { return scaleShiftMinMax; }
            set { scaleShiftMinMax = value; }
        }

        /// <summary>
        /// Min and max red start color value of the particles to be randomed between
        /// </summary>
        public MinMaxFloat ColorRedStartMinMax
        {
            get { return colorRedStartMinMax; }
            set { colorRedStartMinMax = value; }
        }

        /// <summary>
        /// Min and max red end color value of the particles to be randomed between
        /// </summary>
        public MinMaxFloat ColorRedEndMinMax
        {
            get { return colorRedEndMinMax; }
            set { colorRedEndMinMax = value; }
        }

        /// <summary>
        /// Min and max green start color value of the particles to be randomed between
        /// </summary>
        public MinMaxFloat ColorGreenStartMinMax
        {
            get { return colorGreenStartMinMax; }
            set { colorGreenStartMinMax = value; }
        }

        /// <summary>
        /// Min and max green end color value of the particles to be randomed between
        /// </summary>
        public MinMaxFloat ColorGreenEndMinMax
        {
            get { return colorGreenEndMinMax; }
            set { colorGreenEndMinMax = value; }
        }

        /// <summary>
        /// Min and max blue start color value of the particles to be randomed between
        /// </summary>
        public MinMaxFloat ColorBlueStartMinMax
        {
            get { return colorBlueStartMinMax; }
            set { colorBlueStartMinMax = value; }
        }

        /// <summary>
        /// Min and max blue end color value of the particles to be randomed between
        /// </summary>
        public MinMaxFloat ColorBlueEndMinMax
        {
            get { return colorBlueEndMinMax; }
            set { colorBlueEndMinMax = value; }
        }

        /// <summary>
        /// Min and max start alpha value of the particles to be randomed between
        /// </summary>
        public MinMaxFloat AlphaValueStartMinMax
        {
            get { return alphaValueStartMinMax; }
            set { alphaValueStartMinMax = value; }
        }

        /// <summary>
        /// Min and max end alpha value of the particles to be randomed between
        /// </summary>
        public MinMaxFloat AlphaValueEndMinMax
        {
            get { return alphaValueEndMinMax; }
            set { alphaValueEndMinMax = value; }
        }

        #endregion

        #region Constructor

        public EmitterData()
        {

        }

        #endregion
    }

    #region ContentTypeReader Class

    public class EmitterDataReader : ContentTypeReader<EmitterData>
    {
        protected override EmitterData Read(ContentReader input,
            EmitterData existingInstance)
        {
            if (existingInstance == null)
            {
                throw new ArgumentNullException("existingInstance");
            }

            existingInstance.TexturePath = input.ReadString();
            if (existingInstance.TexturePath != string.Empty)
            {
                existingInstance.Texture =
                    input.ContentManager.Load<Texture2D>(existingInstance.TexturePath);
            }
            existingInstance.EmitterPosition = input.ReadVector2();
            existingInstance.ParticleCount = input.ReadInt32();
            existingInstance.ParticleMaxSpawnCount = input.ReadInt32();
            existingInstance.IsRotationDirectionRandom = input.ReadBoolean();
            existingInstance.IsRotationClockwise = input.ReadBoolean();
            existingInstance.EmissionAngle = input.ReadObject<MinMaxFloat>();
            existingInstance.LifeMinMax = input.ReadObject<MinMaxFloat>();
            existingInstance.VelocityMinMax = input.ReadObject<MinMaxFloat>();
            existingInstance.AccelerationMinMax = input.ReadObject<MinMaxFloat>();
            existingInstance.RotationMinMax = input.ReadObject<MinMaxFloat>();
            existingInstance.RotationSpeedMinMax = input.ReadObject<MinMaxFloat>();
            existingInstance.ScaleMinMax = input.ReadObject<MinMaxFloat>();
            existingInstance.ScaleShiftMinMax = input.ReadObject<MinMaxFloat>();
            existingInstance.ColorRedStartMinMax = input.ReadObject<MinMaxFloat>();
            existingInstance.ColorRedEndMinMax = input.ReadObject<MinMaxFloat>();
            existingInstance.ColorGreenStartMinMax = input.ReadObject<MinMaxFloat>();
            existingInstance.ColorGreenEndMinMax = input.ReadObject<MinMaxFloat>();
            existingInstance.ColorBlueStartMinMax = input.ReadObject<MinMaxFloat>();
            existingInstance.ColorBlueEndMinMax = input.ReadObject<MinMaxFloat>();
            existingInstance.AlphaValueStartMinMax = input.ReadObject<MinMaxFloat>();
            existingInstance.AlphaValueEndMinMax = input.ReadObject<MinMaxFloat>();

            return existingInstance;
        }
    }
    #endregion
}
